<!DOCTYPE html>
<html lang="en">
  <head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
  <meta content="" name="keywords">

  <title> Golang之nil - </title>
  <meta name="description" content="" />
  <meta property="og:title" content="Golang之nil" />
  <meta name="twitter:title" content="Golang之nil" />
  <meta name="description" content="golang中的 nil ，很多人都误以为与Java、PHP等编程语言中的 null 一样。但是实际上Golang的niu复杂得多">
  <meta property="og:description" content="golang中的 nil ，很多人都误以为与Java、PHP等编程语言中的 null 一样。但是实际上Golang的niu复杂得多">
  <meta name="twitter:description" content="golang中的 nil ，很多人都误以为与Java、PHP等编程语言中的 null 一样。但是实际上Golang的niu复杂得多">
  <meta name="author" content="{Description { .Site.Author.name }}"/>
  <meta name="twitter:card" content="summary" />
  <meta property="og:url" content="https://systemime.github.io/blog/2019-02/golang%E4%B9%8Bnil/" />
  <meta property="og:type" content="website" />
  <meta property="og:site_name" content="听风的小站" />

  <meta name="generator" content="Hugo 0.67.0" />
  <link rel="canonical" href="https://systemime.github.io/blog/2019-02/golang%E4%B9%8Bnil/" />
  <link rel="alternate" href="https://systemime.github.io/index.xml" type="application/rss+xml" title="听风的小站">
  <script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/jquery-1.12.4.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  
  
  <link rel="stylesheet" href="https://systemime.github.io/css/main.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/my.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/pace.css" />
  <link rel="stylesheet" href="https://cdn.plyr.io/3.4.7/plyr.css">
  <link rel="stylesheet" href="https://systemime.github.io/css/lightgallery.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/baguetteBox.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/search.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/reward.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/share.min.css" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" />
  <link rel="stylesheet" href="https://systemime.github.io/css/pygment_highlights.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/highlight.min.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/toc.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/lightbox.css" />
  <link rel="stylesheet" href="https://systemime.github.io/live2d/css/live2d.css" />
  
  <link href="https://systemime.github.io/css/video-js.css" rel="stylesheet">


<meta name="baidu-site-verification" content="g8IYR9SNLF" />
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?cffe439e37449bb1c07ab26ab56484bb";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

<link rel="stylesheet" href="https://systemime.github.io/css/prism.css" />









<script src="https://systemime.github.io/js/pace.min.js" data-no-instant></script>



<script src="https://systemime.github.io/js/instantclick.min.js" data-no-instant></script>
   <script data-no-instant>
   InstantClick.on('change', function(isInitialLoad) {
     if (isInitialLoad === false) {
       if (typeof MathJax !== 'undefined') 
         MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
       if (typeof prettyPrint !== 'undefined') 
         prettyPrint();
       if (typeof _hmt !== 'undefined')  
         _hmt.push(['_trackPageview', location.pathname + location.search]);
       if (typeof ga !== 'undefined')  
           ga('send', 'pageview', location.pathname + location.search);
     }
   });
   InstantClick.init();
</script>




<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gist-embed/2.7.1/gist-embed.min.js"></script>


<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
  (adsbygoogle = window.adsbygoogle || []).push({
    google_ad_client: "ca-pub-3925981084585036",
    enable_page_level_ads: true
  });
</script>



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe.min.css" integrity="sha256-sCl5PUOGMLfFYctzDW3MtRib0ctyUvI9Qsmq2wXOeBY=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/default-skin/default-skin.min.css" integrity="sha256-BFeI1V+Vh1Rk37wswuOYn5lsTcaU96hGaI7OUVCLjPc=" crossorigin="anonymous" />



<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

<div class="pswp__bg"></div>

<div class="pswp__scroll-wrap">
    
    <div class="pswp__container">
      <div class="pswp__item"></div>
      <div class="pswp__item"></div>
      <div class="pswp__item"></div>
    </div>
    
    <div class="pswp__ui pswp__ui--hidden">
    <div class="pswp__top-bar">
      
      <div class="pswp__counter"></div>
      <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
      <button class="pswp__button pswp__button--share" title="Share"></button>
      <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
      <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
      
      
      <div class="pswp__preloader">
        <div class="pswp__preloader__icn">
          <div class="pswp__preloader__cut">
            <div class="pswp__preloader__donut"></div>
          </div>
        </div>
      </div>
    </div>
    <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
      <div class="pswp__share-tooltip"></div>
    </div>
    <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
    </button>
    <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
    </button>
    <div class="pswp__caption">
      <div class="pswp__caption__center"></div>
    </div>
    </div>
    </div>
</div>

</head>

  <body>
    <nav class="navbar navbar-default navbar-fixed-top navbar-custom">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#main-navbar">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="https://systemime.github.io">听风的小站</a>
    </div>
    <div class="collapse navbar-collapse" id="main-navbar">
      <ul class="nav navbar-nav navbar-right">
        
          
            <li>
		    <a title="博客" href="https://systemime.github.io/blog/">博客</a>
              
              
            </li>
          
        
          
            <li>
		    <a title="片刻" href="https://systemime.github.io/moment/">片刻</a>
              
              
            </li>
          
        
          
            <li>
		    <a title="关于" href="https://systemime.github.io/about/">关于</a>
              
              
            </li>
          
        
          
            <li>
		    <a title="留言" href="https://systemime.github.io/message/">留言</a>
              
              
            </li>
          
        

        

        
        
      </ul>
    </div>

    <div class="avatar-container">
      <div class="avatar-img-border">
        
      </div>
    </div>

  </div>
</nav>






    
  
  
  




  

  <header class="header-section ">
    
    <div class="intro-header no-img">
      
      <div class="container">
        <div class="row">
          <div class="col-lg-12 col-md-12 col-md-offset-0">
            <div class="blog-heading">
                <h1 align="center">Golang之nil</h1>
                
                
            </div>
          </div>
        </div>
      </div>
    </div>
  </header>


    
<div class="container" role="main" itemscope itemtype="http://schema.org/Article">
    <div class="row">
        <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
            
            
            
<div>
    <section id="datecount">
        <h4 id="date"> Mon Feb 11, 2019</h4>
    </section>
    <h5 id="wc">1600 Words|Read in about 4 Min|本文总阅读量<span id="busuanzi_value_page_pv"></span>次</h5>
    <h5 id="tags">Tags: 
        
        <a href="https://systemime.github.iotags/go/">Go</a> &nbsp;
        
        <a href="https://systemime.github.iotags/nil/">nil</a> &nbsp;
    </h5>
</div>

            
            <article role="main" class="blog-post" itemprop="articleBody" id="content">
                
<aside class="toc">
    <div id='anchors-navbar'>
        <i class='fa fa-anchor'></i>
        <nav id="TableOfContents">
  <ul>
    <li><a href="#总结">总结</a></li>
  </ul>
</nav>
    </div>
    
</aside>


                <p>golang中的<strong><code>nil</code></strong>，很多人都误以为与Java、PHP等编程语言中的<strong>null</strong>一样。但是实际上Golang的niu复杂得多了，如果不信，那我们继续往下阅读。
<strong><code>nil</code></strong> 为预声明的标示符，定义在<strong><code>builtin/builtin.go</code></strong></p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="c1">// nil is a predeclared identifier representing the zero value for a
</span><span class="c1">// pointer, channel, func, interface, map, or slice type.
</span><span class="c1">// Type must be a pointer, channel, func, interface, map, or slice type
</span><span class="c1"></span><span class="kd">var</span> <span class="kc">nil</span> <span class="nx">Type</span> 

<span class="c1">// Type is here for the purposes of documentation only. It is a stand-in
</span><span class="c1">// for any Go type, but represents the same type for any given function
</span><span class="c1">// invocation.
</span><span class="c1"></span><span class="kd">type</span> <span class="nx">Type</span> <span class="kt">int</span>
</code></pre></div><h1 id="nil的零值">nil的零值</h1>
<p>按照Go语言规范，任何类型在未初始化时都对应一个零值：布尔类型是false，整型是0，字符串是&rdquo;&quot;，而指针、函数、interface、slice、channel和map的零值都是nil。
<strong>PS：这里没有说结构体struct的零值为nil，因为struct的零值与其属性有关</strong>
<strong><code>nil</code></strong>没有默认的类型，尽管它是多个类型的零值，必须显式或隐式指定每个nil用法的明确类型。</p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>

    <span class="c1">// 明确.
</span><span class="c1"></span>    <span class="nx">_</span> <span class="p">=</span> <span class="p">(</span><span class="o">*</span><span class="kd">struct</span><span class="p">{})(</span><span class="kc">nil</span><span class="p">)</span>
    <span class="nx">_</span> <span class="p">=</span> <span class="p">[]</span><span class="nb">int</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span>
    <span class="nx">_</span> <span class="p">=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span><span class="nb">bool</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span>
    <span class="nx">_</span> <span class="p">=</span> <span class="kd">chan</span> <span class="nb">string</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span>
    <span class="nx">_</span> <span class="p">=</span> <span class="p">(</span><span class="kd">func</span><span class="p">())(</span><span class="kc">nil</span><span class="p">)</span>
    <span class="nx">_</span> <span class="p">=</span> <span class="kd">interface</span><span class="p">{}(</span><span class="kc">nil</span><span class="p">)</span>

    <span class="c1">// 隐式.
</span><span class="c1"></span>    <span class="kd">var</span> <span class="nx">_</span> <span class="o">*</span><span class="kd">struct</span><span class="p">{}</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="kd">var</span> <span class="nx">_</span> <span class="p">[]</span><span class="kt">int</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="kd">var</span> <span class="nx">_</span> <span class="kd">map</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span><span class="kt">bool</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="kd">var</span> <span class="nx">_</span> <span class="kd">chan</span> <span class="kt">string</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="kd">var</span> <span class="nx">_</span> <span class="kd">func</span><span class="p">()</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="kd">var</span> <span class="nx">_</span> <span class="kd">interface</span><span class="p">{}</span> <span class="p">=</span> <span class="kc">nil</span>
<span class="p">}</span>
</code></pre></div><p>如果关注过golang关键字的同学就会发现，里面并没有<strong><code>nil</code></strong>，也就是说<strong><code>nil</code></strong>并不是关键字，那么就可以在代码中定义<strong><code>nil</code></strong>，那么<strong><code>nil</code></strong>就会被隐藏。</p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>

<span class="kn">import</span> <span class="s">&#34;fmt&#34;</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="kc">nil</span> <span class="o">:=</span> <span class="mi">123</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span> <span class="c1">// 123
</span><span class="c1"></span>    <span class="kd">var</span> <span class="nx">_</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span> <span class="p">=</span> <span class="kc">nil</span> <span class="c1">//cannot use nil (type int) as type map[string]int in assignment
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><h1 id="nil类型的地址和值大小">nil类型的地址和值大小</h1>
<p><strong><code>nil</code></strong>类型的所有值的内存布局始终相同,换一句话说就是：不同类型<strong><code>nil</code></strong>的内存地址是一样的。</p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
    <span class="s">&#34;fmt&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">m</span> <span class="kd">map</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span><span class="kt">string</span>
    <span class="kd">var</span> <span class="nx">ptr</span> <span class="o">*</span><span class="kt">int</span>
    <span class="kd">var</span> <span class="nx">sl</span> <span class="p">[]</span><span class="kt">int</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%p\n&#34;</span><span class="p">,</span> <span class="nx">m</span><span class="p">)</span>       <span class="c1">//0x0
</span><span class="c1"></span>    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%p\n&#34;</span><span class="p">,</span> <span class="nx">ptr</span> <span class="p">)</span>    <span class="c1">//0x0
</span><span class="c1"></span>    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%p\n&#34;</span><span class="p">,</span> <span class="nx">sl</span> <span class="p">)</span>     <span class="c1">//0x0
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><p>业务中一般将<strong><code>nil</code></strong>值表示为异常。<strong><code>nil</code></strong>值的大小始终与其类型与<strong><code>nil</code></strong>值相同的<strong><code>non-nil</code></strong>值大小相同。因此, 表示不同零值的<strong><code>nil</code></strong>标识符可能具有不同的大小。</p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>

<span class="kn">import</span> <span class="p">(</span>
    <span class="s">&#34;fmt&#34;</span>
    <span class="s">&#34;unsafe&#34;</span>
<span class="p">)</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">p</span> <span class="o">*</span><span class="kd">struct</span><span class="p">{}</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nf">Sizeof</span><span class="p">(</span> <span class="nx">p</span> <span class="p">)</span> <span class="p">)</span> <span class="c1">// 8
</span><span class="c1"></span>
    <span class="kd">var</span> <span class="nx">s</span> <span class="p">[]</span><span class="kt">int</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nf">Sizeof</span><span class="p">(</span> <span class="nx">s</span> <span class="p">)</span> <span class="p">)</span> <span class="c1">// 24
</span><span class="c1"></span>
    <span class="kd">var</span> <span class="nx">m</span> <span class="kd">map</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span><span class="kt">bool</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nf">Sizeof</span><span class="p">(</span> <span class="nx">m</span> <span class="p">)</span> <span class="p">)</span> <span class="c1">// 8
</span><span class="c1"></span>
    <span class="kd">var</span> <span class="nx">c</span> <span class="kd">chan</span> <span class="kt">string</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nf">Sizeof</span><span class="p">(</span> <span class="nx">c</span> <span class="p">)</span> <span class="p">)</span> <span class="c1">// 8
</span><span class="c1"></span>
    <span class="kd">var</span> <span class="nx">f</span> <span class="kd">func</span><span class="p">()</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nf">Sizeof</span><span class="p">(</span> <span class="nx">f</span> <span class="p">)</span> <span class="p">)</span> <span class="c1">// 8
</span><span class="c1"></span>
    <span class="kd">var</span> <span class="nx">i</span> <span class="kd">interface</span><span class="p">{}</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nf">Sizeof</span><span class="p">(</span> <span class="nx">i</span> <span class="p">)</span> <span class="p">)</span> <span class="c1">// 16
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><p>大小是编译器和体系结构所依赖的。以上打印结果为64位体系结构和正式 Go 编译器。对于32位体系结构, 打印的大小将是一半。</p>
<p>对于正式 Go 编译器, 同一种类的不同类型的两个<strong><code>nil</code></strong>值的大小始终相同。例如, 两个不同的切片类型 ( []int和[]string) 的两个<strong><code>nil</code></strong>值始终相同。</p>
<h1 id="nil值比较">nil值比较</h1>
<ol>
<li>不同类型的<strong><code>nil</code></strong>是不能比较的。</li>
</ol>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
    <span class="s">&#34;fmt&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">m</span> <span class="kd">map</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span><span class="kt">string</span>
    <span class="kd">var</span> <span class="nx">ptr</span> <span class="o">*</span><span class="kt">int</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="nx">m</span> <span class="o">==</span> <span class="nx">ptr</span><span class="p">)</span> <span class="c1">//invalid operation: m == ptr (mismatched types map[int]string and *int)
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><p>在 Go 中, 两个不同可比较类型的两个值只能在一个值可以隐式转换为另一种类型的情况下进行比较。具体来说, 有两个案例两个不同的值可以比较:
* 两个值之一的类型是另一个的基础类型。
* 两个值之一的类型实现了另一个值的类型 (必须是接口类型)。</p>
<p><strong><code>nil</code></strong> <strong>值比较并没有脱离上述规则。</strong></p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
  <span class="s">&#34;fmt&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">type</span> <span class="nx">IntPtr</span> <span class="o">*</span><span class="kt">int</span>
  <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nf">IntPtr</span><span class="p">(</span><span class="kc">nil</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="o">*</span><span class="kt">int</span><span class="p">)(</span><span class="kc">nil</span><span class="p">))</span>            <span class="c1">//true
</span><span class="c1"></span>  <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">((</span><span class="kd">interface</span><span class="p">{})(</span><span class="kc">nil</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="o">*</span><span class="kt">int</span><span class="p">)(</span><span class="kc">nil</span><span class="p">))</span>    <span class="c1">//false
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><ol start="2">
<li>同一类型的两个<strong><code>nil</code></strong>值可能无法比较 因为golang中存在map、slice和函数类型是不可比较类型，它们有一个别称为<strong><code>不可比拟的类型</code></strong>，所以比较它们的<strong><code>nil</code></strong>亦是非法的。</li>
</ol>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
    <span class="s">&#34;fmt&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">v1</span> <span class="p">[]</span><span class="kt">int</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="kd">var</span> <span class="nx">v2</span> <span class="p">[]</span><span class="kt">int</span> <span class="p">=</span> <span class="kc">nil</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">v1</span> <span class="o">==</span> <span class="nx">v2</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">((</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">)(</span><span class="kc">nil</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">)(</span><span class="kc">nil</span><span class="p">))</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">((</span><span class="kd">func</span><span class="p">())(</span><span class="kc">nil</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="kd">func</span><span class="p">())(</span><span class="kc">nil</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div><p><strong><code>不可比拟的类型</code></strong>的值缺是可以与“纯nil”进行比较。</p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
    <span class="s">&#34;fmt&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">((</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">)(</span><span class="kc">nil</span><span class="p">)</span> <span class="o">==</span> <span class="kc">nil</span><span class="p">)</span>  <span class="c1">//true
</span><span class="c1"></span>    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">((</span><span class="kd">func</span><span class="p">())(</span><span class="kc">nil</span><span class="p">)</span> <span class="o">==</span> <span class="kc">nil</span><span class="p">)</span>           <span class="c1">//true
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><ol start="3">
<li>两<strong><code>nil</code></strong>值可能不相等
如果两个比较的nil值之一是一个接口值, 而另一个不是, 假设它们是可比较的, 则比较结果总是 false。原因是在进行比较之前, 接口值将转换为接口值的类型。转换后的接口值具有具体的动态类型, 但其他接口值没有。这就是为什么比较结果总是错误的。</li>
</ol>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
    <span class="s">&#34;fmt&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span> <span class="p">(</span><span class="kd">interface</span><span class="p">{})(</span><span class="kc">nil</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="o">*</span><span class="kt">int</span><span class="p">)(</span><span class="kc">nil</span><span class="p">)</span> <span class="p">)</span> <span class="c1">// false
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><h1 id="常见问题">常见问题</h1>
<ol>
<li>函数返回</li>
</ol>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kd">func</span> <span class="nf">nilReturn</span><span class="p">()</span> <span class="p">(</span><span class="kt">string</span><span class="p">,</span><span class="kt">error</span><span class="p">)</span>  <span class="p">{</span>

    <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span><span class="kc">nil</span>  <span class="c1">//cannot use nil as type string in return argument
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><p>因为<strong><code>error</code></strong>是接口类型所以<strong><code>error</code></strong>类型没有报错。
2. map的nil key map的key为指针、函数、interface、slice、channel和map，则key可以为nil。</p>
<div class="highlight"><pre class="chroma"><code class="language-go" data-lang="go"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
    <span class="s">&#34;fmt&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">mmap</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="o">*</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="p">)</span>
    <span class="nx">a</span><span class="o">:=</span><span class="s">&#34;a&#34;</span>
    <span class="nx">mmap</span><span class="p">[</span><span class="o">&amp;</span><span class="nx">a</span><span class="p">]</span> <span class="p">=</span> <span class="mi">1</span>
    <span class="nx">mmap</span><span class="p">[</span><span class="kc">nil</span><span class="p">]</span> <span class="p">=</span> <span class="mi">99</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">mmap</span><span class="p">)</span>   <span class="c1">//map[0xc042008220:1 &lt;nil&gt;:99]
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><h2 id="总结">总结</h2>
<p><strong><code>nil</code></strong>之所以比较难以理解因为我们经常混淆了nil值和nil类型，希望各位同学细细品味其中区别。</p>

                <br />
                <div style="text-align:center;color: #ccc;font-size:16px;font-family: cursive;">-------他日江湖相逢 <i class="fa fa-umbrella"></i> 再当杯酒言欢-------</div>
                <script src="https://systemime.github.io/js/particle.js"></script>
                
                
                <div class="social-share" data-initialized="true" data-wechat-qrcode-title="不扫别后悔">
    <center>
    <font style="font-size:18px;color:darkcyan;">分享到：</font>
    <a href="#" class="social-share-icon icon-weibo"></a>
    <a href="#" class="social-share-icon icon-wechat"></a>
    <a href="#" class="social-share-icon icon-twitter"></a>
    <a href="#" class="social-share-icon icon-linkedin"></a>
    <a href="#" class="social-share-icon icon-facebook"></a>
    <a href="#" class="social-share-icon icon-qq"></a>
    </center>
</div>


<script src="https://hugo-picture.oss-cn-beijing.aliyuncs.com/social-share.min.js"></script>

                
            </article>

            <ul class="pager blog-pager">
                
                <li class="previous">
                    <a href="https://systemime.github.io/blog/2019-02/linux%E5%86%85%E5%AD%98%E5%92%8C%E7%A3%81%E7%9B%98%E6%B8%85%E7%90%86/" data-toggle="tooltip" data-placement="top" title="Linux内存和磁盘清理">&larr; Previous Post</a>
                </li>
                 
                <li class="next">
                    <a href="https://systemime.github.io/blog/2019-02/ubuntu-%E5%AE%89%E8%A3%85-docker-ce/" data-toggle="tooltip" data-placement="top" title="Ubuntu 安装 Docker CE">Next Post &rarr;</a>
                </li>
                
            </ul>
            
            <div>
                 
            </div>
            
            
            
              
            
            </div>
        </div>
        <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
            
            
        </div>
    </div>
    </section>
</div>

    <div class="rocket"><img src="https://systemime.github.io/img/rocket_up.png" alt="" width="100" height="100"></div>
<script>
    $(function () {
      $(window).scroll(function () {
        
        if ($(window).scrollTop() >= 1000) {
          $('.rocket').stop().fadeIn(1000);
        }else {
          $('.rocket').stop().fadeOut(1000);
        }
      })
      
      $('.rocket').click(function () {
        $('html,body').stop().animate({scrollTop:0},400);
       
      })
    })

</script>

    
    <div id="landlord">
        <div class="message" style="opacity:0"></div>
        <canvas id="live2d" width="280" height="250" class="live2d"></canvas>
        <div class="hide-button">隐藏</div>
    </div>
    
    <footer id="copyright">
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <ul class="list-inline text-center footer-links">
          
          
        </ul>
        <p class="credits copyright text-muted">
        &copy;2017-2018
          
          &nbsp;&bull;&nbsp;
          September 20,2019
          updated
          
            &nbsp;&bull;&nbsp;
            <a href="https://systemime.github.io">Home</a>
          
        </p>

        <p class="credits theme-by text-muted">
        <a href="https://servicemesher.github.io" target="_blank">ServiceMesher</a>&nbsp;&bull;&nbsp;<a href="https://github.com/yangchuansheng/k8s-knowledge" target="_blank">Kubernetes 知识图谱</a>
        <br />
        <span id="busuanzi_container_site_pv">
            本站已被访问 <span id="busuanzi_value_site_pv"></span> 次啦
        </span>
        <span id="busuanzi_container_site_uv">
            &ensp;|&ensp;&thinsp;您是第 <span id="busuanzi_value_site_uv"></span> 位到访的小伙伴喔
        </span>
        </p>
        
        <p class="credits theme-by text-muted">
          <a href="http://gohugo.io">Hugo v0.67.0</a> powered &nbsp;&bull;&nbsp; Theme by <a href="http://deanattali.com/beautiful-jekyll/">Beautiful Jekyll</a> adapted to <a href="https://github.com/halogenica/beautifulhugo">Beautiful Hugo</a>
          
          <center><section class="credits theme-by text-muted">
    <span class="footer__copyright">
    <div>
    <span id="span_dt_dt"> </span>
    <script language="javascript">
      function show_date_time(){
        window.setTimeout("show_date_time()", 1000);
        BirthDay=new Date("7/8/2017 10:56:12");
        today=new Date();
        timeold=(today.getTime()-BirthDay.getTime());
        sectimeold=timeold/1000
        secondsold=Math.floor(sectimeold);
        msPerDay=24*60*60*1000
        e_daysold=timeold/msPerDay
        daysold=Math.floor(e_daysold);
        e_hrsold=(e_daysold-daysold)*24;
        hrsold=Math.floor(e_hrsold);
        e_minsold=(e_hrsold-hrsold)*60;
        minsold=Math.floor((e_hrsold-hrsold)*60);
        seconds=Math.floor((e_minsold-minsold)*60);
        span_dt_dt.innerHTML="本博客已经开心运行 "+daysold+" 天 "+hrsold+" 小时 "+minsold+" 分 "+seconds+" 秒";
      }
      show_date_time();
    </script>
    </div>
</script>
</section>
</center>
        </p>
      </div>
    </div>
  </div>
</footer>


<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/bootstrap.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/photoswipe-ui-default.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/photoswipe.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/auto-render.min.js"></script>
<script src="https://systemime.github.io/js/main.js"></script>
<script src="https://systemime.github.io/js/clipboard.min.js"></script>
<script src="https://systemime.github.io/js/prism.js?t=123"></script>
<script src="https://systemime.github.io/js/highlight.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/katex.min.js"></script>
<script src="https://systemime.github.io/js/reward.js"></script>
<script src="https://systemime.github.io/js/canvas_ribbon.js"></script>
<script> renderMathInElement(document.body); </script>

<script src="https://systemime.github.io/js/baguetteBox.js"></script>
<script> baguetteBox.run('.gallery');</script>






<script async defer src="https://buttons.github.io/buttons.js"></script>


<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
<script type="text/javascript" src="https://systemime.github.io/js/quicklink.umd.js"></script>
<script>
window.addEventListener('load', () =>{
   quicklink();
});
</script>



<script type="text/javascript">
 
var a_idx = 0;
jQuery(document).ready(function($) {
    $("body").click(function(e) {
        var a = new Array("Docker", "Kubernetes", "Prometheus", "Envoy", "Istio", "Service Mesh", "Cloud Native");
        var $i = $("<span />").text(a[a_idx]);
        a_idx = (a_idx + 1) % a.length;
        var x = e.pageX,
        y = e.pageY;
        function randomColor() {
          var flakeColor = new Array("#FFDA65", "#00BFFF", "#BA55D3", "#FFA07A", "#87CEEB", "#FFB6C1");
          var snowColor = flakeColor[Math.floor(flakeColor.length * Math.random())];
          return snowColor;
        }
        $i.css({
            "z-index": 999999999999999999999999999999999999999999999999999999999999999999999,
            "top": y - 20,
            "left": x,
            "position": "absolute",
            "font-weight": "bold",
            "color": randomColor()
        });
        $("body").append($i);
        $i.animate({
            "top": y - 180,
            "opacity": 0
        },
        1500,
        function() {
            $i.remove();
        });
    });
});
</script>


<script type="text/javascript" src="https://systemime.github.io/js/lightbox.js"></script>











<script src="https://cdn.plyr.io/3.4.7/plyr.js"></script>
<script>const player = new Plyr('#player');</script>


<script async defer src="https://buttons.github.io/buttons.js"></script>


  </body>
</html>

